package com.example.w.service.impl;

import com.example.w.common.exception.SystemException;
import com.example.w.common.pojo.MenuItem;
import com.example.w.common.pojo.Order;
import com.example.w.common.pojo.OrderItem;
import com.example.w.common.pojo.Table;
import com.example.w.dao.MenuItemDao;
import com.example.w.dao.OrderDao;
import com.example.w.dao.OrderItemDao;
import com.example.w.dao.TableDao;
import com.example.w.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.*;
import java.util.List;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderDao orderDao;
    @Autowired
    OrderItemDao orderItemDao;
    @Autowired
    MenuItemDao menuItemDao;
    @Autowired
    TableDao tableDao;

    @Override
    //根据桌子id和支付状态查询订单
    public List<Order> getOrderByTableIdAndPayStatus(Integer tableId, Integer paystatus) {
        Map<String, Integer> searchCondition = new HashMap<>();
        searchCondition.put("tableId", tableId);
        searchCondition.put("paystatus", paystatus);
        List<Order> orders = orderDao.selectByTableIdAndPaystatus(searchCondition);
        for (Order order: orders) {
            tagMenuItemName(order);
        }
        return orders;
    }

    //下单
    @Override
    public void addOrder(Order order){
        Table table;    //记录下单的桌子

        //判断下单信息是否正确完整
        if (!order.isInfoCompleteForAddition()) {
            throw new SystemException("下单信息不完整");
        }
        table = tableDao.selectByPrimaryKey(order.getTableId());
        if(table == null){
            throw new SystemException("该桌子不存在");
        }
        //计算金额
        calculateSubtotal(order);
        //设置日期和订单状态，写入订单
        order.setDate(new Date());
        order.setPaid(false);
        orderDao.insertSelective(order);
        for (OrderItem orderItem: order.getOrderItemList()) {
            orderItem.setOrderId(order.getId());
        }
        orderItemDao.insertOrderItems(order.getOrderItemList());
    }

    //加菜
    @Override
    public void additionalMenuItem(Order addedOrder) {
        Order order;
        if (!addedOrder.isInfoCompleteForAdditionalMenuItem()) {
            throw new SystemException("加菜信息不全");
        }
        order = orderDao.selectByPrimaryKey(addedOrder.getId());
        if (order == null) {
            throw new SystemException("该订单不存在");
        }
        //计算orderItem金额并更新订单
        calculateSubtotal(addedOrder);
        order.addOrderItem(addedOrder.getOrderItemList());
        //更新总订单，写入新的orderItem
        orderDao.updateByPrimaryKey(order);
        for (OrderItem orderItem: addedOrder.getOrderItemList()) {
            orderItem.setOrderId(order.getId());
        }
        orderItemDao.insertOrderItems(addedOrder.getOrderItemList());
    }

    @Override
    public Order getCurrentOrder(Integer tableId) {
        Order order = getOrderByTableIdAndPayStatus(tableId, 0).get(0);
        tagMenuItemName(order);
        return order;
    }

    //换台
    @Override
    public void changeTable(long orderId, int tableId){
        Order order = orderDao.selectByPrimaryKey(orderId);
        if (order == null) {
            throw new SystemException("该订单不存在");
        }else if (order.isPaid()) {
            throw new SystemException("该订单已支付");
        }
        Table table = tableDao.selectByPrimaryKey(tableId);
        //判断桌子是否存在
        if (table != null) {
            order.setTableId(tableId);
            orderDao.updateByPrimaryKeySelective(order);
        }else throw new SystemException("该桌子不存在");
    }

    @Override
    //根据订单id查询订单
    public Order gerOrderByOrderId(Long id){
        Order order = orderDao.selectByPrimaryKey(id);
        tagMenuItemName(order);
        return order;
    }

    /**
     * 计算小计和判断菜品是否可下单
     */
    private void calculateSubtotal(Order order) {
        Map<Long, MenuItem> register;   //记录下单菜品的状态
        MenuItem menuItem;  //记录要添加的菜品
        //计算金额
        //查询添加的菜品，检查菜品是否存在，状态是否有，获得价格
        register = getMenuItems(order.getMenuItemId());
        for (OrderItem orderItem: order.getOrderItemList()) {
            menuItem = register.get(orderItem.getMenuItemId());
            if (menuItem == null) {
                throw new SystemException("选择的菜品不存在");
            }else if (!menuItem.isAvailable()) {
                throw new SystemException("\"" + menuItem.getMenuItemName() + "\"已售罄");
            }
            BigDecimal subtotal = menuItem.getPrice().multiply(new BigDecimal(orderItem.getQuantity()));
            orderItem.setSubtotal(subtotal);
        }

    }

    private void tagMenuItemName(Order order) {
        //获取需要标注的菜品
        Map<Long, MenuItem> register = getMenuItems(order.getMenuItemId());
        //标注菜品名称到orderItem
        for (OrderItem orderItem: order.getOrderItemList()) {
            orderItem.setMenuItemName(
                    register.get(orderItem.getMenuItemId()).getMenuItemName()
            );
        }
    }

    private Map<Long, MenuItem> getMenuItems(long[] menuItemIds) {
        List<MenuItem> menuItemsToAdd;  //记录查找到的菜品
        Map<Long, MenuItem> register;   //记录查找到的菜品
        menuItemsToAdd = menuItemDao.selectByPrimaryKeys(menuItemIds);
        register = new HashMap<>();
        for (MenuItem menuItemToAdd: menuItemsToAdd) {
            register.put(menuItemToAdd.getId(), menuItemToAdd);
        }
        return register;
    }

}
